package com.brzjomo.secretiveworld.object.item;

import com.brzjomo.secretiveworld.init.ModBlocks;
import com.google.common.collect.Multimap;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.material.Material;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.IItemTier;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.item.TieredItem;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.Rotation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class CrowbarItem extends TieredItem {
	private final float attackDamage;
	private final float attackSpeed;

	private static Block[] list = { Blocks.CHEST, Blocks.TRAPPED_CHEST, Blocks.BARREL, ModBlocks.CRATE.get(),
			Blocks.COMPOSTER, Blocks.ACACIA_TRAPDOOR, Blocks.BIRCH_TRAPDOOR, Blocks.DARK_OAK_TRAPDOOR,
			Blocks.JUNGLE_TRAPDOOR, Blocks.OAK_TRAPDOOR, Blocks.SPRUCE_TRAPDOOR, Blocks.ACACIA_DOOR, Blocks.BIRCH_DOOR,
			Blocks.DARK_OAK_DOOR, Blocks.JUNGLE_DOOR, Blocks.OAK_DOOR, Blocks.SPRUCE_DOOR, Blocks.ACACIA_FENCE_GATE,
			Blocks.BIRCH_FENCE_GATE, Blocks.DARK_OAK_FENCE_GATE, Blocks.JUNGLE_FENCE_GATE, Blocks.OAK_FENCE_GATE,
			Blocks.SPRUCE_FENCE_GATE };

	public CrowbarItem(IItemTier tierIn, float attackDamageIn, float attackSpeedIn, Properties builder) {
		super(tierIn, builder);
		this.attackSpeed = attackSpeedIn;
		this.attackDamage = attackDamageIn + tierIn.getAttackDamage();
	}

	public float getAttackDamage() {
		return this.attackDamage;
	}

	public boolean canPlayerBreakBlockWhileHolding(BlockState state, World worldIn, BlockPos pos, PlayerEntity player) {
		return !player.isCreative();
	}

	public float getDestroySpeed(ItemStack stack, BlockState state) {
		boolean flag = false;
		Block block = state.getBlock();
		for (Block i : list) {
			if (block == i) {
				flag = true;
			}
		}
		if (flag) {
			return 10.0F;
		} else if (block == Blocks.COBWEB) {
			return 15.0F;
		} else {
			Material material = state.getMaterial();
			return material != Material.PLANTS && material != Material.TALL_PLANTS && material != Material.CORAL
					&& !state.isIn(BlockTags.LEAVES) && material != Material.GOURD ? 0.8F : 1.3F;
		}
	}

	public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) {
		stack.damageItem(1, attacker, (p_220045_0_) -> {
			p_220045_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
		});
		return true;
	}

	public boolean onBlockDestroyed(ItemStack stack, World worldIn, BlockState state, BlockPos pos,
			LivingEntity entityLiving) {
		boolean flag = false;
		Block block = state.getBlock();
		for (Block i : list) {
			if (block == i) {
				flag = true;
			}
		}
		if (flag) {
			stack.damageItem(1, entityLiving, (p_220044_0_) -> {
				p_220044_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
			});
		} else if (state.getBlockHardness(worldIn, pos) == 0.0F) {
			stack.damageItem(0, entityLiving, (p_220044_0_) -> {
				p_220044_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
			});
		} else {
			stack.damageItem(2, entityLiving, (p_220044_0_) -> {
				p_220044_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
			});
		}

		return true;
	}

	public boolean canHarvestBlock(BlockState blockIn) {
		boolean flag = false;
		Block block = blockIn.getBlock();
		for (Block i : list) {
			if (block == i) {
				flag = true;
			}
		}
		if (flag) {
			return true;
		} else if (block == Blocks.COBWEB) {
			return true;
		} else {
			return false;
		}
	}

	@SuppressWarnings("deprecation")
	public Multimap<String, AttributeModifier> getAttributeModifiers(EquipmentSlotType equipmentSlot) {
		Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(equipmentSlot);
		if (equipmentSlot == EquipmentSlotType.MAINHAND) {
			multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER,
					"Weapon modifier", (double) this.attackDamage, AttributeModifier.Operation.ADDITION));
			multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER,
					"Weapon modifier", (double) this.attackSpeed, AttributeModifier.Operation.ADDITION));
		}

		return multimap;
	}

	@Override
	public ActionResultType onItemUse(ItemUseContext context) {
		World world = context.getWorld();
		BlockPos blockpos = context.getPos();
		BlockState blockstate = world.getBlockState(blockpos);
		Block block = blockstate.getBlock();
		PlayerEntity player = context.getPlayer();
		Hand hand = context.getHand();
		ItemStack itemstack = player.getHeldItem(hand);
		if (block != null) {
			if (!world.isRemote) {
				if (player != null) {
					Rotation rot = Rotation.CLOCKWISE_90;
					double x = context.getHitVec().x - (double) blockpos.getX();
					double z = context.getHitVec().z - (double) blockpos.getZ();
					if (player.getHorizontalFacing() == Direction.NORTH) {
						rot = (x > 0.5D) ? Rotation.COUNTERCLOCKWISE_90 : Rotation.CLOCKWISE_90;
					} else if (player.getHorizontalFacing() == Direction.SOUTH) {
						rot = (x < 0.5D) ? Rotation.COUNTERCLOCKWISE_90 : Rotation.CLOCKWISE_90;
					} else if (player.getHorizontalFacing() == Direction.EAST) {
						rot = (z > 0.5D) ? Rotation.COUNTERCLOCKWISE_90 : Rotation.CLOCKWISE_90;
					} else if (player.getHorizontalFacing() == Direction.WEST) {
						rot = (z < 0.5D) ? Rotation.COUNTERCLOCKWISE_90 : Rotation.CLOCKWISE_90;
					}
					world.setBlockState(blockpos, blockstate.rotate(rot), 2);
				}
			}
			world.playSound(player, blockpos, SoundEvents.BLOCK_ANVIL_LAND, SoundCategory.BLOCKS, 1.0F, 1.0F);
			itemstack.damageItem(1, player, (p_220045_0_) -> {
				p_220045_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
			});
			return ActionResultType.SUCCESS;
		} else {
			return ActionResultType.PASS;
		}
	}
}
